﻿using System;
using BusinessBingo.CommandHandlers.Base;
using BusinessBingo.CommandHandlers.Interfaces;
using BusinessBingo.CommandHandlers.Results;
using BusinessBingo.Commands;
using BusinessBingo.Data.Interfaces;
using BusinessBingo.Model;
using BusinessBingo.Model.Interfaces;

namespace BusinessBingo.CommandHandlers
{
    public class CreateGroupCommandHandler :
        BaseCommandHandler,
        ICreateGroupCommandHandler
    {
        private IGenerateUrlCommandHandler _generateUrlCommandHandler;
        private IGroupRepository _groupRepository;

        public CreateGroupCommandHandler(
            IGenerateUrlCommandHandler generateUrlCommandHandler,
            IGroupRepository groupRepository,
            IValidationState validationState,
            IUnitOfWork unitOfWork)
            : base(validationState, unitOfWork)
        {
            this._generateUrlCommandHandler = generateUrlCommandHandler;
            this._groupRepository = groupRepository;
        }

        public CreateGroupCommandHandlerResult Execute(CreateGroupCommand createGroupCommand)
        {
            CreateGroupCommandHandlerResult result = new CreateGroupCommandHandlerResult();

            if(createGroupCommand == default(CreateGroupCommand))
                throw new ArgumentNullException("CreateGroupCommand");
            if (string.IsNullOrWhiteSpace(createGroupCommand.Name))
                this._validationState.AddError<CreateGroupCommand>(x => x.Name, ErrorTypes.Empty);

            if (this._validationState.IsValid == false)
                return result;

            GenerateUrlCommand generateUrlCommand = new GenerateUrlCommand(createGroupCommand.Name);
            
            GenerateUrlCommandHandlerResult generateUrlCommandResult = this._generateUrlCommandHandler.Execute(generateUrlCommand);

            Group group = new Group();
            group.Name = createGroupCommand.Name;
            group.Url = generateUrlCommandResult.Url;
            group.Language = createGroupCommand.Language;

            group = this._groupRepository.AddItem(group);

            base.Complete();

            result.Succeeded = true;
            result.Group = group;

            return result;
        }
    }
}